import axios, { AxiosRequestConfig } from 'axios';
import qs from 'qs';
import { createDiscreteApi } from 'naive-ui';
import { useMainStore } from '@/store';

const { message } = createDiscreteApi(['message', 'dialog', 'notification', 'loadingBar']);
const env = import.meta.env;

const http = axios.create({
  baseURL: env.VITE_API_BASEURL,
  timeout: 5000
});

let mainStore;

http.interceptors.request.use(
  cfg => {
    mainStore = mainStore || useMainStore();
    const token = mainStore.token;
    if (cfg.headers) {
      if (cfg.headers['Content-Type'] == 'application/x-www-form-urlencoded') {
        cfg.data = qs.stringify(cfg.data);
      }
    }
    if (token) {
      cfg.headers['X-TOKEN'] = token;
    }
    return cfg;
  },
  e => Promise.reject(e)
);

http.interceptors.response.use(
  res => res.data,
  e => {
    message.warning(e.response.data.message);
    return Promise.reject(e);
  }
);

let MockUrl = (url: string, mock: boolean) => (env.VITE_USE_MOCK == 'true' && mock ? '/mock' + url : url);

const handUrl = (url: string) => {
  let p = env.VITE_DOWNLOAD_URL.replace(/\/$/, '');
  let u = url.replace(/^\//, '');
  return p + '/' + u;
};

let Post =
  <T>(url: string, headers?: AxiosRequestConfig, useMock: boolean = true) =>
  (data?: T) =>
    http.post<any, any, T>(MockUrl(url, useMock), data, headers);

let Get =
  <T>(url: string, headers?: AxiosRequestConfig, useMock: boolean = true) =>
  (data?: T) =>
    http.get<any, any, T>(MockUrl(url, useMock), { params: data, ...headers });

let Download = <T>(url: string) => {
  return (params?: T) => {
    window.open(handUrl(url) + '?' + qs.stringify(params));
  };
};

type BlobParams = {
  fileName: string;
  fileType: string;
  [x: string]: any;
};

let DownloadBlob = <T>(url: string) => {
  return (data: BlobParams & T) =>
    Post<BlobParams & T>(url, { responseType: 'blob' })(data).then(res => {
      if (res instanceof Blob === false) return;
      const blob: any = new Blob([res]);
      var downloadElement = document.createElement('a');
      var href = window.URL.createObjectURL(blob);
      downloadElement.href = href;
      downloadElement.download = data.fileName + '.' + data.fileType;
      document.body.appendChild(downloadElement);
      downloadElement.click();
      document.body.removeChild(downloadElement);
      window.URL.revokeObjectURL(href);
    });
};

let Upload = <T>(url: string) => {
  return (params?: T) => ({
    action: handUrl(url) + '?' + qs.stringify(params),
    headers: {
      'X-TOKEN': mainStore.token
    }
  });
};

export { Post, Get, Download, Upload, DownloadBlob };
